package cn.edu.hbpu.service;

import cn.edu.hbpu.common.utils.DateUtils;
import cn.edu.hbpu.mapper.AttendMapper;
import cn.edu.hbpu.mapper.ReAttendMapper;
import cn.edu.hbpu.pojo.Attend;
import cn.edu.hbpu.pojo.ReAttend;
import cn.edu.hbpu.pojo.ReAttendCustom;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by yuwenteng on 2017/9/22.
 */
@Service("reAttendServiceImpl")
public class ReAttendServiceImpl implements ReAttendService {

    //批准学生发起的任务补签
    private static final Byte REATTEND_APPROVE = 2;

    //否决学生发起的任务补签
    private static final Byte REATTEND_UNAPPROVE = 3;

    //设置attend表中status字段为正常
    private static final byte ATTEND_NORMAL = 1;

    //更新attend中早签到时间
    private static final int MORNING_HOUR = 8;
    private static final int MORNING_MINUTE = 00;

    //更新attend中晚签到时间
    private static final int EVENING_HOUR = 17;
    private static final int EVENING_MINUTE = 00;

    @Autowired
    private ReAttendMapper reAttendMapper;

    @Autowired
    private AttendMapper attendMapper;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    /**
     * @Author yuwenteng
     * @Date 2017/9/22 22:47
     * @Description 根据学生姓名查询数据库考勤补签数据信息
     */
    public List<ReAttend> findReAttendInfo(String stuName) {
        return reAttendMapper.selectReAttendInfo(stuName);
    }

    /**
     * @Author yuwenteng
     * @Date 2017/9/26 0:13
     * @Description 设置流程变量，开启流程实例并关联业务
     */
    @Transactional
    public void commitReAttendInfo(ReAttend reAttend) {
        //查询数据库中是否存在当前任务的记录
        ReAttend reAttendCurrent = reAttendMapper.selectReAttendCurrent(reAttend.getAttendId());
        //如果数据库中不存在当前任务的记录
        if (reAttendCurrent == null) {
            //更新数据库信息，插入reattend的记录
            reAttendMapper.insertSelective(reAttend);
            //使用reattend对象获取流程定义的KEY
            String processDefinitionKey = reAttend.getClass().getSimpleName();
            //通过流程变量设置当前办理人和下一个流程任务办理人
            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("student", reAttend.getReAttendStarter());
            variables.put("teacher", reAttend.getCurrentHandler());
            //根据attendId查询reattend记录中的ID
            Long reAttendId = reAttendMapper.selectByAttendId(reAttend.getAttendId());
            if (reAttendId != null) {
                //通过objId设置activiti表中的BUSINESS_KEY_字段让流程实例关联业务
                String objId = processDefinitionKey + "." + reAttendId;
                //根据processDefinitionKey和objId启动流程实例同时设置流程变量
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, objId, variables);
                //根据流程实例ID获取当前任务
                Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
                //根据任务ID完成任务提交工作
                taskService.complete(task.getId());
            }
        } else
            //反之数据库中存在这个任务的记录则直接返回
            return;
    }

    /**
     * @Author yuwenteng
     * @Date 2017/9/28 12:20
     * @Description 查询数据库re_attend表中中正在审批的个人补签任务信息
     */
    public List<ReAttend> findReAttendProcessed(String stuName) {
        return reAttendMapper.selectReAttendProcessedByName(stuName);
    }

    /**
     * @Author yuwenteng
     * @Date 2017/9/26 12:31
     * @Description 办理人根据任务对象查询流程实例中的BUSINESS_KEY_字段获取业务信息
     */
    public List<ReAttendCustom> queryTaskList(String teacherName) {
        //根据任务办理人查询当前任务信息
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(teacherName).list();
        List<ReAttendCustom> reAttendList = null;
        if (CollectionUtils.isNotEmpty(taskList)) {
            reAttendList = new ArrayList<ReAttendCustom>();
            for (Task task : taskList) {
                //根据任务对象获取当前流程实例ID
                String processInstanceId = task.getProcessInstanceId();
                //根据流程实例ID查询activiti的执行对象表返回流程实例
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                //通过流程实例获取关联业务的objId
                String objId = processInstance.getBusinessKey();
                if (StringUtils.isNotBlank(objId)) {
                    //拆分objId拿到reattend记录的ID
                    Long reAttendId = Long.parseLong(objId.split("\\.")[1]);
                    //根据reAttendId查询表的信息返回reattend对象
                    ReAttendCustom reAttendCustom = reAttendMapper.selectReAttendInfoById(reAttendId);
                    reAttendCustom.setTaskId(task.getId());
                    reAttendList.add(reAttendCustom);
                }
            }
        }
        return reAttendList;
    }

    /**
     * @Author yuwenteng
     * @Date 2017/9/28 15:53
     * @Description 提交审批的补签任务，结束流程实例，并设置数据库中re_attend和attend表中的status字段的值
     */
    @Transactional
    public void completeTeacherTask(ReAttendCustom reAttendCustom) {
        //根据re_attend表的id查询记录
        ReAttend reAttend = reAttendMapper.selectByPrimaryKey(reAttendCustom.getId());
        //如果approveFlag的值是2，则为批准，更新re_attend表中和attend表中字段
        if (reAttendCustom.getApproveFlag() == REATTEND_APPROVE) {
            //设置re_attend表中状态为通过
            reAttend.setStatus(REATTEND_APPROVE);
            //更新re_attend表中记录信息
            reAttendMapper.updateByPrimaryKey(reAttend);
            //根据attend_id查询attend表中记录
            Attend attend = attendMapper.selectByPrimaryKey(reAttend.getAttendId());
            //更新attend表中的异常数据
            attend.setAttendStatus(ATTEND_NORMAL);
            attend.setAbsenceMorning(null);
            attend.setAbsenceEvening(null);
            Date morning = DateUtils.getDate(MORNING_HOUR, MORNING_MINUTE);
            attend.setAttendMorning(morning);
            Date evening = DateUtils.getDate(EVENING_HOUR, EVENING_MINUTE);
            attend.setAttendEvening(evening);
            attendMapper.updateByPrimaryKey(attend);
        } else {
            //approveFlag的值是3,则为否决，更新re_attend状态
            reAttend.setStatus(REATTEND_UNAPPROVE);
            //更新re_attend表中记录信息
            reAttendMapper.updateByPrimaryKey(reAttend);
        }
        //根据任务id提交完成审批补签的任务
        taskService.complete(reAttendCustom.getTaskId());
    }

    /**
    *@Author yuwenteng
    *@Date 2017/9/30 11:30
    *@Description 根据任务办理人姓名查询当前办理任务的总数
    */
    public Integer findCountOfTask(String teacherName) {
        //查询到当前办理任务的集合
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(teacherName).list();
        Integer count = null;
        //获取当前办理任务的总数
        if (CollectionUtils.isNotEmpty(taskList)) {
            //返回当前任务数
            count = taskList.size();
        }
        return count;
    }
}







